﻿namespace KP_CommonLibrary.KP_CommonControls.NumericInput
{
    // using DevExpress.Data.Mask;
    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Globalization;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    using System.Security.Permissions;
    using System.Windows.Forms;
    using KP_CommonLibrary.KP_CommonControls.NumericInput;
    using DevComponents.DotNetBar.Controls;
    using KP_CommonLibrary.KP_CommonControls;

    [ToolboxItem(true)]
    public class MaskBox : KP_TextBox
    {
        public MaskBox()
            : base()
        {
            
        }
        private int _assignValueCount;
        private int _initializeInProgress;
        private MaskManager _manager;
        private MaskProperties _mask;
        private MaskStrategy.ManagedStrategy _strategyManaged;
        private MaskStrategy.SimpleStrategy _strategySimple;
        private int imeChar;
        private const int VK_CONTROL = 0x11;
        private const int VK_HOME = 0x24;
        private const int VK_LEFT = 0x25;
        private const int VK_RIGHT = 0x27;
        private const int VK_SHIFT = 0x10;
        private const int WM_KEYDOWN = 0x100;
        //private bool hasMouseFocus = false;
        private bool alreadyFocused = false;
        public event EventHandler EditTextChanged;

        public event ChangingEventHandler EditTextChanging;

        protected virtual void AssignValueLock()
        {
            this._assignValueCount++;
        }

        protected override void OnGotFocus(EventArgs e)
        {
            if (MouseButtons.None == MouseButtons)
            {
                SelectEditText();
            }
           // this.BeginInvoke(new MethodInvoker(SelectEditText));
            base.OnGotFocus(e);
        }

        protected override void OnLostFocus(EventArgs e)
        {
           // hasMouseFocus = false;
            alreadyFocused = false;
            base.OnLostFocus(e);
        }
        public void SelectEditText()
        {
            if (EditText != null && EditText.Length > 0)
                MaskBoxSelect(0, EditText.Length);

        }
        protected override void OnMouseUp(MouseEventArgs e)
        {
            //if (!alreadyFocused && MouseButtons.Left == e.Button)
            //{
            //    base.OnMouseUp(e);
            //}
            //else
            //{
            //    SelectEditText();
            //    hasMouseFocus = true;
            //}
            
            if (!alreadyFocused && MaskBoxSelectionLength == 0)
            {
                SelectEditText();
                alreadyFocused = true;
            }

        }
        protected virtual void AssignValueUnLock()
        {
            this._assignValueCount--;
        }

        protected virtual void AutoLeaveHandler()
        {
        }

        private void BaseScrollToCaret()
        {
            base.ScrollToCaret();
        }

        private void BaseSelect(int start, int length)
        {
            base.Select(start, length);
        }



        private void BaseUndo()
        {
            base.Undo();
        }

        private void BaseWndProc(ref Message m)
        {
            base.WndProc(ref m);
        }

        public void BeginInitMask()
        {
            this._initializeInProgress++;
            if (!this.IsInitializeInProgress)
            {
                this.ChangeManager();
            }
        }

        private void ChangeManager()
        {
            this.ChangeManager(this.Mask);
        }

        private void ChangeManager(MaskProperties mask)
        {
            MaskManager manager;
            if (this.IsInitializeInProgress || (mask.MaskType == MaskType.None))
            {
                manager = null;
            }
            else
            {
                manager = this.CreateMaskManagerWithCheck(mask);
                manager.EditTextChanged += new EventHandler(this.OnManagerEditTextChanged);
                manager.EditTextChanging += new MaskChangingEventHandler(this.OnManagerEditTextChanging);
                manager.LocalEditAction += new CancelEventHandler(this.OnLocalEditAction);
            }
            if (this._manager != null)
            {
                this._manager.EditTextChanged -= new EventHandler(this.OnManagerEditTextChanged);
                this._manager.EditTextChanging -= new MaskChangingEventHandler(this.OnManagerEditTextChanging);
                this._manager.LocalEditAction -= new CancelEventHandler(this.OnLocalEditAction);
            }
            this._manager = manager;
        }

        private void ClearStratedies()
        {
            this._strategyManaged = null;
            this._strategySimple = null;
        }

        protected virtual MaskManager CreateMaskManager(MaskProperties mask)
        {
            return mask.CreateDefaultMaskManager();
        }

        private MaskManager CreateMaskManagerWithCheck(MaskProperties mask)
        {
            MaskManager manager = this.CreateMaskManager(mask);
            if (manager == null)
            {
                throw new NotImplementedException(string.Format(CultureInfo.InvariantCulture, "The manager cannot be created for the mask {1} of {0} type. Specify another type of mask or implement the TextEdit.CreateManager method.", new object[] { mask.MaskType, mask.EditMask }));
            }
            return manager;
        }

        private void CursorAtSelectionStartTo(int position)
        {
            byte[] keyStates = new byte[0x100];
            GetKeyboardState(keyStates);
            try
            {
                int baseSelectionStart;
                byte[] buffer2 = (byte[])keyStates.Clone();
                buffer2[0x10] = 0x80;
                if (position < (this.BaseSelectionStart - position))
                {
                    buffer2[0x11] = 0x80;
                    SetKeyboardState(buffer2);
                    Message message = new Message
                    {
                        HWnd = base.Handle,
                        WParam = (IntPtr)0x24,
                        Msg = 0x100
                    };
                    this.DefWndProc(ref message);
                }
                buffer2[0x11] = 0;
                SetKeyboardState(buffer2);
                bool flag = position < this.BaseSelectionStart;
                Message m = new Message
                {
                    HWnd = base.Handle,
                    WParam = flag ? ((IntPtr)0x25) : ((IntPtr)0x27),
                    Msg = 0x100
                };
                do
                {
                    baseSelectionStart = this.BaseSelectionStart;
                    if (flag)
                    {
                        if (baseSelectionStart <= position)
                        {
                            return;
                        }
                    }
                    else if (baseSelectionStart >= position)
                    {
                        return;
                    }
                    this.DefWndProc(ref m);
                }
                while (baseSelectionStart != this.BaseSelectionStart);
            }
            finally
            {
                SetKeyboardState(keyStates);
            }
        }

        public void EndInitMask()
        {
            this._initializeInProgress--;
            if (!this.IsInitializeInProgress)
            {
                this.ChangeManager();
            }
        }

        protected virtual bool FireSpinRequest(bool isUp)
        {
            return this.MaskBoxSpin(isUp);
        }

        protected internal void FlushPendingEditActions()
        {
            this.CurrentMaskStrategy.FlushPendingEditActions();
        }

        protected virtual void ForceVisibleText(string value)
        {
            this.BaseText = value;
        }

        public static string GetClipboardText()
        {
            IDataObject dataObject;
            try
            {
                dataObject = Clipboard.GetDataObject();
            }
            catch
            {
                return string.Empty;
            }
            string data = null;
            if (dataObject.GetDataPresent(DataFormats.UnicodeText))
            {
                data = (string)dataObject.GetData(DataFormats.UnicodeText);
            }
            else if (dataObject.GetDataPresent(DataFormats.Text))
            {
                data = (string)dataObject.GetData(DataFormats.Text);
            }
            return (data ?? string.Empty);
        }

        public bool GetIsSelectAllMode()
        {
            return this.CurrentMaskStrategy.GetIsSelectAllMode();
        }

        [DllImport("USER32.dll")]
        private static extern bool GetKeyboardState(byte[] keyStates);
        private MaskStrategy GetManagedStrategy()
        {
            if (this._strategyManaged == null)
            {
                this._strategyManaged = new MaskStrategy.ManagedStrategy(this);
            }
            return this._strategyManaged;
        }

        private MaskStrategy GetSimpleStrategy()
        {
            if (this._strategySimple == null)
            {
                this._strategySimple = new MaskStrategy.SimpleStrategy(this);
                this._strategySimple.CatchUpAfterCreation();
            }
            return this._strategySimple;
        }

        public bool IsNeededCursorKey(Keys keyData)
        {
            return this.CurrentMaskStrategy.IsNeededCursorKey(keyData);
        }

        public void MaskBoxDeselectAll()
        {
            this.CurrentMaskStrategy.DeselectAll();
        }

        public void MaskBoxScrollToCaret()
        {
            this.CurrentMaskStrategy.ScrollToCaret();
        }

        public void MaskBoxSelect(int start, int length)
        {
            this.CurrentMaskStrategy.Select(start, length);
        }

        public void MaskBoxSelectAll()
        {
            this.CurrentMaskStrategy.SelectAll();
        }

        public bool MaskBoxSpin(bool isUp)
        {
            return this.CurrentMaskStrategy.DoSpin(isUp);
        }

        public void MaskBoxUndo()
        {
            this.CurrentMaskStrategy.Undo();
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);
            if (!e.Handled)
            {
                this.CurrentMaskStrategy.DoAfterKeyDown(e);
            }
        }

        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            base.OnKeyPress(e);
            if (!e.Handled)
            {
                this.CurrentMaskStrategy.DoAfterKeyPress(e);
            }
        }

        protected override void OnLeave(EventArgs e)
        {
            this.FlushPendingEditActions();
            base.OnLeave(e);
        }

        protected virtual void OnLocalEditAction(object sender, CancelEventArgs e)
        {
            if (this.IsNowReadOnly)
            {
                e.Cancel = true;
            }
        }

        private void OnManagerEditTextChanged(object sender, EventArgs e)
        {
            this.RaiseEditTextChanged();
        }

        private void OnManagerEditTextChanging(object sender, MaskChangingEventArgs e)
        {
            if (!this.IsAssignValueLock)
            {
                if (this.IsNowReadOnly)
                {
                    e.Cancel = true;
                }
                else
                {
                    ChangingEventArgs args = new ChangingEventArgs(e.OldValue, e.NewValue, e.Cancel);
                    this.RaiseEditTextChanging(args);
                    e.Cancel = args.Cancel;
                    e.NewValue = args.NewValue;
                }
            }
        }

        private void OnMaskAfterChanged(object sender, EventArgs e)
        {
            this.ChangeManager();
        }

        private void OnMaskBeforeChanged(object sender, ChangeEventArgs e)
        {
            switch (e.Name)
            {
                case "MaskType":
                    this.ValidateManager((MaskType)e.Value, this.Mask.EditMask, this.Mask.AutoComplete, this.Mask.ShowPlaceHolders, this.Mask.PlaceHolder, this.Mask.SaveLiteral, this.Mask.IgnoreMaskBlank, this.Mask.Culture);
                    return;

                case "EditMask":
                    this.ValidateManager(this.Mask.MaskType, (string)e.Value, this.Mask.AutoComplete, this.Mask.ShowPlaceHolders, this.Mask.PlaceHolder, this.Mask.SaveLiteral, this.Mask.IgnoreMaskBlank, this.Mask.Culture);
                    return;

                case "AutoComplete":
                    this.ValidateManager(this.Mask.MaskType, this.Mask.EditMask, (AutoCompleteType)e.Value, this.Mask.ShowPlaceHolders, this.Mask.PlaceHolder, this.Mask.SaveLiteral, this.Mask.IgnoreMaskBlank, this.Mask.Culture);
                    return;

                case "ShowPlaceHolders":
                    this.ValidateManager(this.Mask.MaskType, this.Mask.EditMask, this.Mask.AutoComplete, (bool)e.Value, this.Mask.PlaceHolder, this.Mask.SaveLiteral, this.Mask.IgnoreMaskBlank, this.Mask.Culture);
                    return;

                case "PlaceHolder":
                    this.ValidateManager(this.Mask.MaskType, this.Mask.EditMask, this.Mask.AutoComplete, this.Mask.ShowPlaceHolders, (char)e.Value, this.Mask.SaveLiteral, this.Mask.IgnoreMaskBlank, this.Mask.Culture);
                    return;

                case "SaveLiteral":
                    this.ValidateManager(this.Mask.MaskType, this.Mask.EditMask, this.Mask.AutoComplete, this.Mask.ShowPlaceHolders, this.Mask.PlaceHolder, (bool)e.Value, this.Mask.IgnoreMaskBlank, this.Mask.Culture);
                    return;

                case "IgnoreMaskBlank":
                    this.ValidateManager(this.Mask.MaskType, this.Mask.EditMask, this.Mask.AutoComplete, this.Mask.ShowPlaceHolders, this.Mask.PlaceHolder, this.Mask.SaveLiteral, (bool)e.Value, this.Mask.Culture);
                    return;

                case "Culture":
                    this.ValidateManager(this.Mask.MaskType, this.Mask.EditMask, this.Mask.AutoComplete, this.Mask.ShowPlaceHolders, this.Mask.PlaceHolder, this.Mask.SaveLiteral, this.Mask.IgnoreMaskBlank, (CultureInfo)e.Value);
                    return;
            }
        }

        protected override void OnMouseWheel(MouseEventArgs e)
        {
            DXMouseEventArgs mouseArgs = DXMouseEventArgs.GetMouseArgs(e);
            base.OnMouseWheel(mouseArgs);
            if (!mouseArgs.Handled)
            {
                mouseArgs.Handled = this.FireSpinRequest(mouseArgs.Delta > 0);
            }
        }

        protected override void OnTextChanged(EventArgs e)
        {
            base.OnTextChanged(e);
            this.CurrentMaskStrategy.DoAfterTextChanged(e);
        }

        public void ProcessF2()
        {
            this.CurrentMaskStrategy.ProcessF2();
        }

        protected override bool ProcessKeyEventArgs(ref Message m)
        {
            if (m.Msg == 0x286)
            {
                this.imeChar++;
                try
                {
                    return base.ProcessKeyEventArgs(ref m);
                }
                finally
                {
                    this.imeChar--;
                }
            }
            return base.ProcessKeyEventArgs(ref m);
        }

        protected internal virtual void RaiseEditTextChanged()
        {
            if (!this.IsAssignValueLock && (this.EditTextChanged != null))
            {
                this.EditTextChanged(this, EventArgs.Empty);
            }
        }

        protected internal virtual void RaiseEditTextChanging(ChangingEventArgs e)
        {
            if (!this.IsAssignValueLock && (this.EditTextChanging != null))
            {
                this.EditTextChanging(this, e);
            }
        }

        public virtual void Reset()
        {
            this.ClearStratedies();
        }

        public void ResetSelection()
        {
            this.CurrentMaskStrategy.ResetSelection();
        }

        protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
        {
        }

        [Obsolete("Use MaskBoxScrollToCaret instead", true)]
        public new void ScrollToCaret()
        {
            throw new NotImplementedException();
        }

        [Obsolete("Use MaskBoxSelect instead", true)]
        public new void Select(int start, int length)
        {
            throw new NotImplementedException();
        }

        [Obsolete("Use MaskBoxSelectAll instead", true)]
        public new void SelectAll()
        {
            throw new NotImplementedException();
        }

        private void SelectAllReversed()
        {
            this.BaseSelectionStart = 0x7fffffff;
            this.CursorAtSelectionStartTo(0);
        }

        [DllImport("USER32.dll")]
        private static extern bool SetKeyboardState(byte[] keyStates);
        [Obsolete("Use MaskBoxUndo instead", true)]
        public new void Undo()
        {
            throw new NotImplementedException();
        }

        private void ValidateManager(MaskType maskType, string editMask, AutoCompleteType autoComplete, bool showPlaceHolders, char placeHolder, bool saveLiteral, bool ignoreMaskBlank, CultureInfo culture)
        {
            if (!this.IsInitializeInProgress && (maskType != MaskType.None))
            {
                MaskProperties mask = new MaskProperties
                {
                    MaskType = maskType,
                    EditMask = editMask,
                    AutoComplete = autoComplete,
                    ShowPlaceHolders = showPlaceHolders,
                    PlaceHolder = placeHolder,
                    SaveLiteral = saveLiteral,
                    IgnoreMaskBlank = ignoreMaskBlank,
                    Culture = culture
                };
                this.CreateMaskManagerWithCheck(mask);
            }
        }

        [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
        protected override void WndProc(ref Message m)
        {
            this.CurrentMaskStrategy.DoWndProc(ref m);
        }

        private bool BaseCanUndo
        {
            get
            {
                return base.CanUndo;
            }
        }

        private string BaseSelectedText
        {
            get
            {
                return base.SelectedText;
            }
            set
            {
                base.SelectedText = value;
            }
        }

        private int BaseSelectionLength
        {
            get
            {
                return base.SelectionLength;
            }
            set
            {
                base.SelectionLength = value;
            }
        }

        private int BaseSelectionStart
        {
            get
            {
                return base.SelectionStart;
            }
            set
            {
                base.SelectionStart = value;
            }
        }

        private string BaseText
        {
            get
            {
                return base.Text;
            }
            set
            {
                base.Text = value;
            }
        }

        [Browsable(false), Obsolete("Use MaskBoxCanUndo instead", true)]
        public new bool CanUndo
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        private MaskStrategy CurrentMaskStrategy
        {
            get
            {
                if (this.IsInitializeInProgress)
                {
                    return this.GetSimpleStrategy();
                }
                if (this.Mask.MaskType == MaskType.None)
                {
                    return this.GetSimpleStrategy();
                }
                return this.GetManagedStrategy();
            }
        }

        [RefreshProperties(RefreshProperties.All), Category("Data")]
        public string EditText
        {
            get
            {
                return this.CurrentMaskStrategy.GetEditText();
            }
            set
            {
                this.AssignValueLock();
                try
                {
                    this.CurrentMaskStrategy.SetEditText(value);
                }
                finally
                {
                    this.AssignValueUnLock();
                }
            }
        }

        [Category("Data")]
        public object EditValue
        {
            get
            {
                return this.CurrentMaskStrategy.GetEditValue();
            }
            set
            {
                this.AssignValueLock();
                try
                {
                    this.CurrentMaskStrategy.SetEditValue(value);
                }
                finally
                {
                    this.AssignValueUnLock();
                }
            }
        }

        protected bool IsAssignValueLock
        {
            get
            {
                return (this._assignValueCount != 0);
            }
        }

        protected internal bool IsIMEProcessing
        {
            get
            {
                return (this.imeChar != 0);
            }
        }

        [Browsable(false)]
        public bool IsInitializeInProgress
        {
            get
            {
                return (this._initializeInProgress != 0);
            }
        }

        [Category("Behavior"), Browsable(false)]
        public bool IsMatch
        {
            get
            {
                return this.CurrentMaskStrategy.GetIsMatch();
            }
        }

        protected virtual bool IsNowReadOnly
        {
            get
            {
                if (!base.ReadOnly)
                {
                    return base.Capture;
                }
                return true;
            }
        }

        [Browsable(false)]
        public virtual bool IsShouldUseEditValue
        {
            get
            {
                return this.CurrentMaskStrategy.GetIsEditValueDifferFromEditText();
            }
        }

        protected virtual bool IsUpdateVisualStateSupressed
        {
            get
            {
                return false;
            }
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Browsable(true), Category("Mask")]
        public MaskProperties Mask
        {
            get
            {
                if (this._mask == null)
                {
                    this.Mask = new MaskProperties();
                }
                return this._mask;
            }
            set
            {
                this.ChangeManager(value);
                if (this._mask != null)
                {
                    this._mask.BeforeChange -= new ChangeEventHandler(this.OnMaskBeforeChanged);
                    this._mask.AfterChange -= new EventHandler(this.OnMaskAfterChanged);
                }
                this._mask = value;
                this._mask.BeforeChange += new ChangeEventHandler(this.OnMaskBeforeChanged);
                this._mask.AfterChange += new EventHandler(this.OnMaskAfterChanged);
            }
        }

        [Browsable(false)]
        public bool MaskBoxCanUndo
        {
            get
            {
                return this.CurrentMaskStrategy.GetCanUndo();
            }
        }

        [Category("Appearance"), Browsable(false)]
        public string MaskBoxSelectedText
        {
            get
            {
                return this.CurrentMaskStrategy.GetSelectedText();
            }
            set
            {
                this.CurrentMaskStrategy.SetSelectedText(value);
            }
        }

        [Category("Appearance"), Browsable(false)]
        public int MaskBoxSelectionLength
        {
            get
            {
                return this.CurrentMaskStrategy.GetSelectionLength();
            }
            set
            {
                this.CurrentMaskStrategy.SetSelectionLength(value);
            }
        }

        [Category("Appearance"), Browsable(false)]
        public int MaskBoxSelectionStart
        {
            get
            {
                return this.CurrentMaskStrategy.GetSelectionStart();
            }
            set
            {
                this.CurrentMaskStrategy.SetSelectionStart(value);
            }
        }

        [RefreshProperties(RefreshProperties.All), Category("Appearance"), Browsable(false)]
        public string MaskBoxText
        {
            get
            {
                return this.CurrentMaskStrategy.GetText();
            }
        }

        protected virtual string NullEditText
        {
            get
            {
                return this.WatermarkText;// string.Empty;
            }
        }





        [Category("Appearance"), Browsable(false)]
        public new string Text
        {
            get
            {
                return EditText;
            }
            set
            {
                EditText = value;
            }
        }

        protected string VisibleText
        {
            get
            {
                return this.CurrentMaskStrategy.GetVisibleText();
            }
        }

        private abstract class MaskStrategy
        {
            private readonly MaskBox _owner;

            protected MaskStrategy(MaskBox owner)
            {
                this._owner = owner;
            }

            public abstract void DeselectAll();
            public abstract void DoAfterKeyDown(KeyEventArgs e);
            public abstract void DoAfterKeyPress(KeyPressEventArgs e);
            public abstract void DoAfterTextChanged(EventArgs e);
            public abstract bool DoSpin(bool isUp);
            public abstract void DoWndProc(ref Message m);
            public abstract void FlushPendingEditActions();
            public abstract bool GetCanUndo();
            public abstract string GetEditText();
            public abstract object GetEditValue();
            public abstract bool GetIsEditValueDifferFromEditText();
            public abstract bool GetIsMatch();
            public abstract bool GetIsSelectAllMode();
            public abstract string GetSelectedText();
            public abstract int GetSelectionLength();
            public abstract int GetSelectionStart();
            public abstract string GetText();
            public abstract string GetVisibleText();
            public abstract bool IsNeededCursorKey(Keys keyData);
            public abstract void ProcessF2();
            public abstract void ResetSelection();
            public abstract void ScrollToCaret();
            public abstract void Select(int start, int length);
            public abstract void SelectAll();
            public abstract void SetEditText(string value);
            public abstract void SetEditValue(object value);
            public abstract void SetSelectedText(string value);
            public abstract void SetSelectionLength(int value);
            public abstract void SetSelectionStart(int value);
            public void Undo()
            {
                this.Owner.BaseUndo();
            }

            protected MaskBox Owner
            {
                get
                {
                    return this._owner;
                }
            }

            public class ManagedStrategy : MaskBox.MaskStrategy
            {
                private bool deferredUpdateVisualStateRequired_;
                private const int EM_CHARFROMPOS = 0xd7;
                private const int EM_SETSEL = 0xb1;
                private const int EM_UNDO = 0xc7;
                private int insideManagerChange;
                private uint lockEmSetSel;
                private const int MB_ICONERROR = 0x10;
                private bool selectAllModeFlag_;
                private const int WM_CAPTURECHANGED = 0x215;
                private const int WM_CLEAR = 0x303;
                private const int WM_COPY = 0x301;
                private const int WM_CUT = 0x300;
                private const int WM_NULL = 0;
                private const int WM_PASTE = 770;
                private const int WM_UNDO = 0x304;
                private uint wndProcDepth;

                public ManagedStrategy(MaskBox owner)
                    : base(owner)
                {
                }

                private bool ClearSelectAllModeFlag()
                {
                    if (this.selectAllModeFlag_)
                    {
                        this.selectAllModeFlag_ = false;
                        return true;
                    }
                    return false;
                }

                public override void DeselectAll()
                {
                    this.ClearSelectAllModeFlag();
                    using (new ManagerChangesMarker(this))
                    {
                        this.Manager.CursorToDisplayPosition(this.Manager.DisplaySelectionStart, false);
                        this.UpdateVisualStateRequire();
                    }
                }

                public override void DoAfterKeyDown(KeyEventArgs e)
                {
                    switch (e.KeyCode)
                    {
                        case Keys.End:
                            {
                                if (!this.KillSelectAllModeFlagIfNeeded(KillSelectAllModeFlagIfNeededBehavior.PrepareForCursorMoveAfterSelectAll))
                                {
                                    e.Handled = true;
                                    return;
                                }
                                using (new ManagerChangesMarker(this))
                                {
                                    if (this.Manager.CursorEnd(e.Shift))
                                    {
                                        this.UpdateVisualStateRequire();
                                    }
                                    else
                                    {
                                        e.Handled = true;
                                    }
                                    return;
                                }
                            }
                        case Keys.Home:
                            {
                                if (!this.KillSelectAllModeFlagIfNeeded(KillSelectAllModeFlagIfNeededBehavior.PrepareForCursorMoveAfterSelectAll))
                                {
                                    e.Handled = true;
                                    return;
                                }
                                using (new ManagerChangesMarker(this))
                                {
                                    if (this.Manager.CursorHome(e.Shift))
                                    {
                                        this.UpdateVisualStateRequire();
                                    }
                                    else
                                    {
                                        e.Handled = true;
                                    }
                                    return;
                                }
                            }
                        case Keys.Left:
                            if (this.KillSelectAllModeFlagIfNeeded(KillSelectAllModeFlagIfNeededBehavior.PrepareForCursorMoveAfterSelectAll))
                            {
                                using (new ManagerChangesMarker(this))
                                {
                                    if (this.Manager.CursorLeft(e.Shift))
                                    {
                                        this.UpdateVisualStateRequire();
                                    }
                                    else
                                    {
                                        e.Handled = true;
                                    }
                                    return;
                                }
                            }
                            e.Handled = true;
                            return;

                        case Keys.Up:
                            base.Owner.FireSpinRequest(true);
                            e.Handled = true;
                            return;

                        case Keys.Right:
                            if (this.KillSelectAllModeFlagIfNeeded(KillSelectAllModeFlagIfNeededBehavior.PrepareForCursorMoveAfterSelectAll))
                            {
                                using (new ManagerChangesMarker(this))
                                {
                                    if (this.Manager.CursorRight(e.Shift))
                                    {
                                        this.UpdateVisualStateRequire();
                                    }
                                    else
                                    {
                                        e.Handled = true;
                                    }
                                    return;
                                }
                            }
                            e.Handled = true;
                            return;

                        case Keys.Down:
                            break;

                        case Keys.Select:
                        case Keys.Print:
                        case Keys.Execute:
                        case Keys.Snapshot:
                        case Keys.Insert:
                            return;

                        case Keys.Delete:
                            if (this.IsSelectAllMode)
                            {
                                this.KillSelectAllModeFlagIfNeeded(KillSelectAllModeFlagIfNeededBehavior.ClearAfterSelectAll);
                                e.Handled = true;
                            }
                            else
                            {
                                using (new ManagerChangesMarker(this))
                                {
                                    if (this.Manager.Delete())
                                    {
                                        if (!this.Manager.IsPlainTextLike)
                                        {
                                            e.Handled = true;
                                        }
                                        this.UpdateVisualStateRequire();
                                    }
                                    else
                                    {
                                        e.Handled = true;
                                        this.ProcessBeepOnError();
                                    }
                                }
                            }
                            return;

                        default:
                            return;
                    }
                    base.Owner.FireSpinRequest(false);
                    e.Handled = true;
                }

                public override void DoAfterKeyPress(KeyPressEventArgs e)
                {
                    switch (e.KeyChar)
                    {
                        case '\x0003':
                            this.DoClipboardCopy();
                            e.Handled = true;
                            break;

                        case '\x0016':
                            this.DoClipboardPaste();
                            e.Handled = true;
                            break;

                        case '\x0018':
                            this.DoClipboardCut();
                            e.Handled = true;
                            break;

                        case '\b':
                            {
                                if (this.IsSelectAllMode)
                                {
                                    this.KillSelectAllModeFlagIfNeeded(KillSelectAllModeFlagIfNeededBehavior.ClearAfterSelectAll);
                                    e.Handled = true;
                                    break;
                                }
                                using (new ManagerChangesMarker(this))
                                {
                                    if (!this.Manager.Backspace())
                                    {
                                        e.Handled = true;
                                        this.ProcessBeepOnError();
                                    }
                                    break;
                                }
                            }
                        default:
                            if (!base.Owner.IsIMEProcessing)
                            {
                                string insertion = this.KeyCharToInsertableString(e.KeyChar);
                                if ((insertion != null) && this.KillSelectAllModeFlagIfNeeded(KillSelectAllModeFlagIfNeededBehavior.PrepareForInsertAfterSelectAll))
                                {
                                    using (new ManagerChangesMarker(this))
                                    {
                                        if (this.Manager.Insert(insertion))
                                        {
                                            if (this.Manager.IsFinal)
                                            {
                                                e.Handled = true;
                                                this.UpdateVisualState();
                                                base.Owner.AutoLeaveHandler();
                                            }
                                        }
                                        else
                                        {
                                            e.Handled = true;
                                            this.ProcessBeepOnError();
                                        }
                                    }
                                }
                            }
                            break;
                    }
                    if (!e.Handled)
                    {
                        if (!this.Manager.IsPlainTextLike)
                        {
                            e.Handled = true;
                        }
                        this.UpdateVisualStateRequire();
                    }
                }

                public override void DoAfterTextChanged(EventArgs e)
                {
                }

                private void DoClear(ref Message m)
                {
                    if (this.IsSelectAllMode)
                    {
                        this.KillSelectAllModeFlagIfNeeded(KillSelectAllModeFlagIfNeededBehavior.ClearAfterSelectAll);
                    }
                    else
                    {
                        using (new ManagerChangesMarker(this))
                        {
                            if (this.Manager.Delete())
                            {
                                if (this.Manager.IsPlainTextLike)
                                {
                                    base.Owner.BaseWndProc(ref m);
                                }
                            }
                            else
                            {
                                this.ProcessBeepOnError();
                            }
                            this.UpdateVisualStateRequire();
                        }
                    }
                }

                private void DoClipboardCopy()
                {
                    if (base.Owner.PasswordChar == '\0')
                    {
                        Clipboard.SetDataObject(base.Owner.MaskBoxSelectedText);
                    }
                }

                private void DoClipboardCut()
                {
                    if (base.Owner.PasswordChar == '\0')
                    {
                        this.DoClipboardCopy();
                        if (this.IsSelectAllMode)
                        {
                            this.KillSelectAllModeFlagIfNeeded(KillSelectAllModeFlagIfNeededBehavior.ClearAfterSelectAll);
                        }
                        else if (this.Manager.IsSelection)
                        {
                            using (new ManagerChangesMarker(this))
                            {
                                if (this.Manager.Delete())
                                {
                                    this.UpdateVisualStateRequire();
                                }
                                else
                                {
                                    this.ProcessBeepOnError();
                                }
                            }
                        }
                    }
                }

                private void DoClipboardPaste()
                {
                    if (this.KillSelectAllModeFlagIfNeeded(KillSelectAllModeFlagIfNeededBehavior.PrepareForInsertAfterSelectAll))
                    {
                        using (new ManagerChangesMarker(this))
                        {
                            if (this.Manager.Insert(MaskBox.GetClipboardText()))
                            {
                                this.UpdateVisualStateRequire();
                            }
                            else
                            {
                                this.ProcessBeepOnError();
                            }
                        }
                    }
                }

                private void DoOnCaptureChanged()
                {
                    if (base.Owner.Focused)
                    {
                        SelectionStruct sel = this.GetSel();
                        this.UpdateManagerPositionsFromCurrentSelections(sel.SelectionAnchor, sel.CursorPosition);
                    }
                }

                public override bool DoSpin(bool isUp)
                {
                    if (this.KillSelectAllModeFlagIfNeeded(KillSelectAllModeFlagIfNeededBehavior.PrepareForCursorMoveAfterSelectAll))
                    {
                        using (new ManagerChangesMarker(this))
                        {
                            if (!isUp)
                            {
                                this.Manager.SpinDown();
                            }
                            else
                            {
                                this.Manager.SpinUp();
                            }
                            this.UpdateVisualStateRequire();
                        }
                    }
                    return true;
                }

                private void DoUndo()
                {
                    if (this.KillSelectAllModeFlagIfNeeded(KillSelectAllModeFlagIfNeededBehavior.PrepareForCursorMoveAfterSelectAll))
                    {
                        using (new ManagerChangesMarker(this))
                        {
                            if (this.Manager.Undo())
                            {
                                this.UpdateVisualStateRequire();
                            }
                            else
                            {
                                this.ProcessBeepOnError();
                            }
                        }
                    }
                }

                public override void DoWndProc(ref Message m)
                {
                    this.wndProcDepth++;
                    try
                    {
                        switch (m.Msg)
                        {
                            case 0x300:
                                this.DoClipboardCut();
                                return;

                            case 0x301:
                                this.DoClipboardCopy();
                                return;

                            case 770:
                                this.DoClipboardPaste();
                                return;

                            case 0x303:
                                this.DoClear(ref m);
                                return;

                            case 0x304:
                            case 0xc7:
                                this.DoUndo();
                                return;

                            case 0x215:
                                this.DoOnCaptureChanged();
                                base.Owner.BaseWndProc(ref m);
                                return;

                            case 0xb1:
                                base.Owner.BaseWndProc(ref m);
                                if (this.lockEmSetSel == 0)
                                {
                                    int wParam = (int)m.WParam;
                                    int lParam = (int)m.LParam;
                                    this.UpdateManagerPositionsFromCurrentSelections(wParam, lParam);
                                }
                                return;
                        }
                        base.Owner.BaseWndProc(ref m);
                    }
                    finally
                    {
                        this.wndProcDepth--;
                        if (this.wndProcDepth == 0)
                        {
                            this.UpdateVisualStateIfRequired();
                        }
                    }
                }

                public override void FlushPendingEditActions()
                {
                    using (new ManagerChangesMarker(this))
                    {
                        if (this.Manager.FlushPendingEditActions())
                        {
                            this.UpdateVisualState();
                        }
                    }
                }

                public override bool GetCanUndo()
                {
                    return this.Manager.CanUndo;
                }

                [DllImport("USER32.dll")]
                private static extern bool GetCaretPos(out GetCaretPosPoint p);
                public override string GetEditText()
                {
                    return this.Manager.GetCurrentEditText();
                }

                public override object GetEditValue()
                {
                    return this.Manager.GetCurrentEditValue();
                }

                public override bool GetIsEditValueDifferFromEditText()
                {
                    return this.Manager.IsEditValueDifferFromEditText;
                }

                public override bool GetIsMatch()
                {
                    return this.Manager.IsMatch;
                }

                public override bool GetIsSelectAllMode()
                {
                    return this.IsSelectAllMode;
                }

                private SelectionStruct GetSel()
                {
                    GetCaretPosPoint point;
                    if (base.Owner.BaseSelectionLength == 0)
                    {
                        return new SelectionStruct(base.Owner.BaseSelectionStart, base.Owner.BaseSelectionStart);
                    }
                    if (this.Manager.DisplaySelectionAnchor == base.Owner.BaseSelectionStart)
                    {
                        return new SelectionStruct(base.Owner.BaseSelectionStart, base.Owner.BaseSelectionStart + base.Owner.BaseSelectionLength);
                    }
                    if (this.Manager.DisplaySelectionAnchor == (base.Owner.BaseSelectionStart + base.Owner.BaseSelectionLength))
                    {
                        return new SelectionStruct(base.Owner.BaseSelectionStart + base.Owner.BaseSelectionLength, base.Owner.BaseSelectionStart);
                    }
                    GetCaretPos(out point);
                    Message m = new Message
                    {
                        HWnd = base.Owner.Handle,
                        Msg = 0xd7,
                        LParam = (IntPtr)(point.x | ((point.y + 2) << 0x10))
                    };
                    base.Owner.DefWndProc(ref m);
                    int result = (int)m.Result;
                    result &= 0xffff;
                    int num2 = Math.Abs((int)(base.Owner.BaseSelectionStart - result));
                    int num3 = Math.Abs((int)((base.Owner.BaseSelectionStart + base.Owner.BaseSelectionLength) - result));
                    result = (num2 < num3) ? base.Owner.BaseSelectionStart : (base.Owner.BaseSelectionStart + base.Owner.BaseSelectionLength);
                    return new SelectionStruct((result != base.Owner.BaseSelectionStart) ? base.Owner.BaseSelectionStart : (base.Owner.BaseSelectionStart + base.Owner.BaseSelectionLength), result);
                }

                public override string GetSelectedText()
                {
                    if (!base.Owner.IsUpdateVisualStateSupressed && this.IsSelectionUpdateMayBeNeeded)
                    {
                        return this.Manager.DisplayText.Substring(this.Manager.DisplaySelectionStart, this.Manager.DisplaySelectionLength);
                    }
                    return base.Owner.BaseSelectedText;
                }

                public override int GetSelectionLength()
                {
                    if (!base.Owner.IsUpdateVisualStateSupressed && this.IsSelectionUpdateMayBeNeeded)
                    {
                        return this.Manager.DisplaySelectionLength;
                    }
                    return base.Owner.BaseSelectionLength;
                }

                public override int GetSelectionStart()
                {
                    if (!base.Owner.IsUpdateVisualStateSupressed && this.IsSelectionUpdateMayBeNeeded)
                    {
                        return this.Manager.DisplaySelectionStart;
                    }
                    return base.Owner.BaseSelectionStart;
                }

                public override string GetText()
                {
                    if (base.Owner.IsUpdateVisualStateSupressed)
                    {
                        return base.Owner.BaseText;
                    }
                    return this.Manager.DisplayText;
                }

                public override string GetVisibleText()
                {
                    if (base.Owner.IsUpdateVisualStateSupressed)
                    {
                        return base.Owner.BaseText;
                    }
                    return this.Manager.DisplayText;
                }

                public override bool IsNeededCursorKey(Keys keyData)
                {
                    if ((keyData & ~Keys.KeyCode) != Keys.None)
                    {
                        return true;
                    }
                    if (!this.IsSelectAllMode)
                    {
                        switch ((keyData & Keys.KeyCode))
                        {
                            case Keys.Left:
                                return this.Manager.CursorLeft((keyData & Keys.Shift) == Keys.Shift, true);

                            case Keys.Right:
                                return this.Manager.CursorRight((keyData & Keys.Shift) == Keys.Shift, true);
                        }
                    }
                    return false;
                }

                private string KeyCharToInsertableString(char keyChar)
                {
                    if (!char.IsControl(keyChar))
                    {
                        return keyChar.ToString(CultureInfo.InvariantCulture);
                    }
                    if (((keyChar == '\r') && base.Owner.Multiline) && base.Owner.AcceptsReturn)
                    {
                        return "\r\n";
                    }
                    if (((keyChar == '\t') && base.Owner.Multiline) && base.Owner.AcceptsTab)
                    {
                        return "\t";
                    }
                    return null;
                }

                private bool KillSelectAllModeFlagIfNeeded(KillSelectAllModeFlagIfNeededBehavior behavior)
                {
                    if (base.Owner.IsNowReadOnly && (behavior != KillSelectAllModeFlagIfNeededBehavior.PrepareForCursorMoveAfterSelectAll))
                    {
                        this.ProcessBeepOnError();
                        return false;
                    }
                    if (this.ClearSelectAllModeFlag())
                    {
                        using (new ManagerChangesMarker(this))
                        {
                            switch (behavior)
                            {
                                case KillSelectAllModeFlagIfNeededBehavior.PrepareForCursorMoveAfterSelectAll:
                                    this.Manager.PrepareForCursorMoveAfterSelectAll();
                                    break;

                                case KillSelectAllModeFlagIfNeededBehavior.PrepareForInsertAfterSelectAll:
                                    this.Manager.PrepareForInsertAfterSelectAll();
                                    break;

                                case KillSelectAllModeFlagIfNeededBehavior.ClearAfterSelectAll:
                                    this.Manager.ClearAfterSelectAll();
                                    break;

                                default:
                                    throw new NotImplementedException(behavior.ToString());
                            }
                            this.UpdateVisualStateRequire();
                        }
                    }
                    return true;
                }

                [DllImport("USER32.dll")]
                private static extern bool MessageBeep(uint uType);
                [DllImport("USER32.dll")]
                private static extern bool PostMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
                private void ProcessBeepOnError()
                {
                    if (base.Owner.Mask.BeepOnError)
                    {
                        MessageBeep(0x10);
                    }
                }

                public override void ProcessF2()
                {
                    if (this.IsSelectAllMode || ((this.GetText().Length > 0) && (this.GetText() == this.GetSelectedText())))
                    {
                        this.DeselectAll();
                    }
                    else
                    {
                        this.SelectAll();
                    }
                }

                public override void ResetSelection()
                {
                    using (new ManagerChangesMarker(this))
                    {
                        this.KillSelectAllModeFlagIfNeeded(KillSelectAllModeFlagIfNeededBehavior.PrepareForCursorMoveAfterSelectAll);
                        this.Manager.CursorHome(false);
                        this.UpdateVisualStateRequire();
                    }
                }

                public override void ScrollToCaret()
                {
                    this.UpdateVisualStateIfRequired();
                    base.Owner.BaseScrollToCaret();
                }

                public override void Select(int start, int length)
                {
                    using (new ManagerChangesMarker(this))
                    {
                        this.Manager.CursorToDisplayPosition(start, false);
                        this.Manager.CursorToDisplayPosition(start + length, true);
                        this.ClearSelectAllModeFlag();
                        this.UpdateVisualStateRequire();
                    }
                }

                public override void SelectAll()
                {
                    this.SetSelectAllModeFlag();
                    this.UpdateVisualStateRequire();
                }

                public override void SetEditText(string value)
                {
                    if (value == null)
                    {
                        value = string.Empty;
                    }
                    if (this.GetEditText() != value)
                    {
                        this.Manager.SetInitialEditText(value);
                    }
                    this.UpdateVisualState();
                }

                public override void SetEditValue(object value)
                {
                    this.Manager.SetInitialEditValue(value);
                    this.UpdateVisualState();
                }

                private bool SetSelectAllModeFlag()
                {
                    if (!this.selectAllModeFlag_)
                    {
                        this.selectAllModeFlag_ = true;
                        return true;
                    }
                    return false;
                }

                public override void SetSelectedText(string value)
                {
                    if (!this.IsSelectAllMode || this.KillSelectAllModeFlagIfNeeded(KillSelectAllModeFlagIfNeededBehavior.PrepareForInsertAfterSelectAll))
                    {
                        using (new ManagerChangesMarker(this))
                        {
                            if (this.Manager.Insert(value))
                            {
                                this.UpdateVisualStateRequire();
                            }
                        }
                    }
                }

                public override void SetSelectionLength(int value)
                {
                    this.UpdateVisualStateIfRequired();
                    base.Owner.BaseSelectionLength = value;
                }

                public override void SetSelectionStart(int value)
                {
                    this.UpdateVisualStateIfRequired();
                    base.Owner.BaseSelectionStart = value;
                }

                private void UpdateCursorPos()
                {
                    if (!this.IsMouseSelectionStarted)
                    {
                        this.lockEmSetSel++;
                        try
                        {
                            if (this.IsSelectAllMode)
                            {
                                base.Owner.SelectAllReversed();
                            }
                            else if (!base.Owner.Focused)
                            {
                                if (this.Manager.DisplayCursorPosition >= this.Manager.DisplaySelectionAnchor)
                                {
                                    base.Owner.BaseSelect(this.Manager.DisplaySelectionStart, this.Manager.DisplaySelectionLength);
                                }
                            }
                            else
                            {
                                SelectionStruct sel = this.GetSel();
                                if ((sel.CursorPosition != this.Manager.DisplayCursorPosition) || (sel.SelectionAnchor != this.Manager.DisplaySelectionAnchor))
                                {
                                    if (this.Manager.DisplayCursorPosition < this.Manager.DisplaySelectionAnchor)
                                    {
                                        if (((this.Manager.DisplaySelectionAnchor != sel.SelectionAnchor) || (sel.CursorPosition > sel.SelectionAnchor)) || ((sel.SelectionAnchor - this.Manager.DisplayCursorPosition) < (this.Manager.DisplayCursorPosition - sel.CursorPosition)))
                                        {
                                            base.Owner.BaseSelect(this.Manager.DisplaySelectionAnchor, 0);
                                            sel = new SelectionStruct(this.Manager.DisplaySelectionAnchor, this.Manager.DisplaySelectionAnchor);
                                        }
                                        base.Owner.CursorAtSelectionStartTo(this.Manager.DisplayCursorPosition);
                                    }
                                    else
                                    {
                                        base.Owner.BaseSelect(this.Manager.DisplaySelectionAnchor, this.Manager.DisplayCursorPosition - this.Manager.DisplaySelectionAnchor);
                                    }
                                    base.Owner.BaseScrollToCaret();
                                }
                            }
                        }
                        finally
                        {
                            this.lockEmSetSel--;
                        }
                    }
                }

                private void UpdateManagerPositionsFromCurrentSelections(int anchor, int caret)
                {
                    int length = base.Owner.BaseText.Length;
                    if (((anchor == 0) && ((caret == -1) || (caret >= length))) || ((caret == 0) && ((anchor == -1) || (anchor >= length))))
                    {
                        this.SetSelectAllModeFlag();
                    }
                    else
                    {
                        this.ClearSelectAllModeFlag();
                        this.Manager.CursorToDisplayPosition(anchor, false);
                        this.Manager.CursorToDisplayPosition(caret, true);
                        if ((base.Owner.BaseText != this.Manager.DisplayText) || (anchor == caret))
                        {
                            this.UpdateVisualStateRequire();
                        }
                    }
                }

                private void UpdateVisualState()
                {
                    this.deferredUpdateVisualStateRequired_ = false;
                    if (!base.Owner.IsDisposed)
                    {
                        bool flag = false;
                        this.lockEmSetSel++;
                        try
                        {
                            if (base.Owner.IsUpdateVisualStateSupressed)
                            {
                                base.Owner.ForceVisibleText(base.Owner.VisibleText);
                                if (base.Owner.Focused)
                                {
                                    base.Owner.SelectAllReversed();
                                }
                                return;
                            }
                            if (base.Owner.BaseText != this.Manager.DisplayText)
                            {
                                flag = true;
                                base.Owner.BaseText = this.Manager.DisplayText;
                            }
                            this.UpdateCursorPos();
                        }
                        finally
                        {
                            this.lockEmSetSel--;
                        }
                        if (flag)
                        {
                            base.Owner.Update();
                        }
                    }
                }

                private void UpdateVisualStateIfRequired()
                {
                    if (this.IsUpdateVisualStateRequired)
                    {
                        this.UpdateVisualState();
                    }
                }

                private void UpdateVisualStateRequire()
                {
                    if (!this.deferredUpdateVisualStateRequired_)
                    {
                        this.deferredUpdateVisualStateRequired_ = true;
                        if (this.wndProcDepth == 0)
                        {
                            PostMessage(base.Owner.Handle, 0, IntPtr.Zero, IntPtr.Zero);
                        }
                    }
                }

                private bool IsMouseSelectionStarted
                {
                    get
                    {
                        if (!base.Owner.Focused)
                        {
                            return false;
                        }
                        if (base.Owner.Capture)
                        {
                            return true;
                        }
                        if ((Control.MouseButtons & MouseButtons.Left) != MouseButtons.Left)
                        {
                            return false;
                        }
                        Point mousePosition = Control.MousePosition;
                        Point point2 = base.Owner.PointToClient(mousePosition);
                        return (((point2.X >= 0) && (point2.Y >= 0)) && ((point2.X < base.Owner.Width) && (point2.Y < base.Owner.Height)));
                    }
                }

                private bool IsSelectAllMode
                {
                    get
                    {
                        return this.selectAllModeFlag_;
                    }
                }

                public bool IsSelectionUpdateMayBeNeeded
                {
                    get
                    {
                        if (this.insideManagerChange == 0)
                        {
                            return this.IsUpdateVisualStateRequired;
                        }
                        return true;
                    }
                }

                private bool IsUpdateVisualStateRequired
                {
                    get
                    {
                        return this.deferredUpdateVisualStateRequired_;
                    }
                }

                private MaskManager Manager
                {
                    get
                    {
                        if (base.Owner._manager == null)
                        {
                            base.Owner.ChangeManager();
                        }
                        return base.Owner._manager;
                    }
                }

                [StructLayout(LayoutKind.Sequential)]
                private struct GetCaretPosPoint
                {
                    public int x;
                    public int y;
                }

                protected enum KillSelectAllModeFlagIfNeededBehavior
                {
                    PrepareForCursorMoveAfterSelectAll,
                    PrepareForInsertAfterSelectAll,
                    ClearAfterSelectAll
                }

                private class ManagerChangesMarker : IDisposable
                {
                    private readonly MaskBox.MaskStrategy.ManagedStrategy Strategy;

                    public ManagerChangesMarker(MaskBox.MaskStrategy.ManagedStrategy strategy)
                    {
                        this.Strategy = strategy;
                        this.Strategy.insideManagerChange++;
                    }

                    public void Dispose()
                    {
                        this.Strategy.insideManagerChange--;
                    }
                }

                [StructLayout(LayoutKind.Sequential)]
                private struct SelectionStruct
                {
                    public readonly int SelectionAnchor;
                    public readonly int CursorPosition;
                    public SelectionStruct(int selectionAnchor, int cursorPosition)
                    {
                        this.SelectionAnchor = selectionAnchor;
                        this.CursorPosition = cursorPosition;
                    }
                }
            }

            public class SimpleStrategy : MaskBox.MaskStrategy
            {
                private string cachedOldText;

                public SimpleStrategy(MaskBox owner)
                    : base(owner)
                {
                }

                internal void CatchUpAfterCreation()
                {
                    this.cachedOldText = base.Owner.BaseText;
                }

                public override void DeselectAll()
                {
                    base.Owner.BaseSelectionLength = 0;
                }

                public override void DoAfterKeyDown(KeyEventArgs e)
                {
                    switch (e.KeyCode)
                    {
                        case Keys.Up:
                            if (!base.Owner.FireSpinRequest(true))
                            {
                                break;
                            }
                            e.Handled = true;
                            return;

                        case Keys.Right:
                            break;

                        case Keys.Down:
                            if (base.Owner.FireSpinRequest(false))
                            {
                                e.Handled = true;
                            }
                            break;

                        default:
                            return;
                    }
                }

                public override void DoAfterKeyPress(KeyPressEventArgs e)
                {
                }

                public override void DoAfterTextChanged(EventArgs e)
                {
                    string baseText = base.Owner.BaseText;
                    if (this.cachedOldText != baseText)
                    {
                        ChangingEventArgs args = new ChangingEventArgs(this.cachedOldText, baseText);
                        base.Owner.RaiseEditTextChanging(args);
                        if (args.Cancel)
                        {
                            base.Owner.BaseText = this.cachedOldText;
                        }
                        else
                        {
                            if (object.ReferenceEquals(baseText, args.NewValue))
                            {
                                this.cachedOldText = baseText;
                            }
                            else
                            {
                                if (args.NewValue == null)
                                {
                                    baseText = string.Empty;
                                }
                                else
                                {
                                    baseText = args.NewValue.ToString();
                                }
                                this.cachedOldText = baseText;
                                base.Owner.BaseText = baseText;
                            }
                            base.Owner.RaiseEditTextChanged();
                        }
                    }
                }

                public override bool DoSpin(bool isUp)
                {
                    return false;
                }

                public override void DoWndProc(ref Message m)
                {
                    base.Owner.BaseWndProc(ref m);
                }

                public override void FlushPendingEditActions()
                {
                }

                public override bool GetCanUndo()
                {
                    return base.Owner.BaseCanUndo;
                }

                public override string GetEditText()
                {
                    return base.Owner.BaseText;
                }

                public override object GetEditValue()
                {
                    return this.GetEditText();
                }

                public override bool GetIsEditValueDifferFromEditText()
                {
                    return false;
                }

                public override bool GetIsMatch()
                {
                    return true;
                }

                public override bool GetIsSelectAllMode()
                {
                    int baseSelectionStart = base.Owner.BaseSelectionStart;
                    int baseSelectionLength = base.Owner.BaseSelectionLength;
                    int length = base.Owner.BaseText.Length;
                    return (((baseSelectionStart == 0) && (baseSelectionLength == length)) || ((baseSelectionStart == -1) && (baseSelectionLength == -1)));
                }

                public override string GetSelectedText()
                {
                    return base.Owner.BaseSelectedText;
                }

                public override int GetSelectionLength()
                {
                    return base.Owner.BaseSelectionLength;
                }

                public override int GetSelectionStart()
                {
                    return base.Owner.BaseSelectionStart;
                }

                public override string GetText()
                {
                    return base.Owner.BaseText;
                }

                public override string GetVisibleText()
                {
                    return base.Owner.BaseText;
                }

                public override bool IsNeededCursorKey(Keys keyData)
                {
                    if ((keyData & ~Keys.KeyCode) == Keys.None)
                    {
                        if (this.GetSelectionLength() == this.GetText().Length)
                        {
                            return false;
                        }
                        switch (keyData)
                        {
                            case Keys.Left:
                                return ((this.GetSelectionStart() != 0) || (this.GetSelectionLength() != 0));

                            case Keys.Up:
                            case Keys.Down:
                                if (base.Owner.Multiline)
                                {
                                    if (this.GetSelectionLength() == this.GetText().Length)
                                    {
                                        return false;
                                    }
                                    return true;
                                }
                                return false;

                            case Keys.Right:
                                return ((this.GetSelectionStart() != this.GetText().Length) || (this.GetSelectionLength() != 0));
                        }
                    }
                    return true;
                }

                public override void ProcessF2()
                {
                    if (base.Owner.BaseSelectionLength == 0)
                    {
                        base.Owner.SelectAllReversed();
                    }
                    else
                    {
                        base.Owner.BaseSelectionLength = 0;
                    }
                }

                public override void ResetSelection()
                {
                    base.Owner.MaskBoxSelect(0, 0);
                }

                public override void ScrollToCaret()
                {
                    base.Owner.BaseScrollToCaret();
                }

                public override void Select(int start, int length)
                {
                    base.Owner.BaseSelect(start, length);
                }

                public override void SelectAll()
                {
                    base.Owner.SelectAllReversed();
                }

                public override void SetEditText(string value)
                {
                    if (value == null)
                    {
                        value = string.Empty;
                    }
                    if ((this.GetEditText() != value) && ((base.Owner.CharacterCasing == CharacterCasing.Normal) || (this.GetEditText().ToLower() != value.ToLower())))
                    {
                        this.cachedOldText = value;
                        base.Owner.BaseText = value;
                    }
                }

                public override void SetEditValue(object value)
                {
                    if (value == null)
                    {
                        value = string.Empty;
                    }
                    string str = value.ToString();
                    this.SetEditText(str);
                }

                public override void SetSelectedText(string value)
                {
                    base.Owner.BaseSelectedText = value;
                }

                public override void SetSelectionLength(int value)
                {
                    base.Owner.BaseSelectionLength = value;
                }

                public override void SetSelectionStart(int value)
                {
                    base.Owner.BaseSelectionStart = value;
                }
            }
        }
    }
}

